#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Socket.hpp"
#include "InetAddr.hpp"
#include "Protocol.hpp"

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cerr << "Usage: " << argv[0] << "server-ip server-port" << std::endl;
        exit(0);
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    SockSPtr sock = std::make_shared<TcpSocket>();
    if (!sock->BuildClientSocket(serverip, serverport))
    {
        std::cerr << "connect error" << std::endl;
        exit(1);
    }
    srand(time(nullptr) ^ getpid());
    const std::string opers = "+-*/%^&";
    int cnt = 3;
    std::string packagestreamqueue;
    while (cnt--)
    {
        int x = rand() % 10;
        usleep(x * 1000);
        int y = rand() % 10;
        usleep(x * y * 10);
        char oper = opers[y % opers.size()];

        // 构建请求
        auto req = Factory::BuildRequestDefault();
        req->Setvalue(x, y, oper);

        // 1.序列化
        std::string reqstr;
        req->Serialize(&reqstr);

        // 2.添加长度报头字段
        reqstr = Encode(reqstr);

        std::cout << "######################################" << std::endl;

        std::cout << "request string : \n"
                  << reqstr << std::endl;

        // 3.发送数据

        sock->Send(reqstr);
        while (true)
        {
            // 4 读取应答
            ssize_t n = sock->Recv(&packagestreamqueue);

            // 5.报文解析 提取报头和有效载荷
            std::string package = Decode(packagestreamqueue);
            if (package.empty())
            {
                continue;
            }
            std::cout << "package: \n"<< package << std::endl;

            // 6. 反序列化
            auto resp = Factory::BuildResponseDefault();
            resp->Deserialize(package);

            // 7.打印结果
            resp->PrintResult();
            break;
        }
        sleep(1);
    }

    return 0;
}